/*
 *  ray.c
 *  Ray Tracer
 *
 *  Created by Chirantan Ekbote on 10/11/10.
 *  Copyright 2010 Ohio State University. All rights reserved.
 *
 */

#include "../include/ray.h"
#include "../include/object.h"	// Needs to be included since we used forward declaration of object in ray.h

int castRay(const ray* r, const struct object* shapes, int* i, double* time) {
	int k, hit = 0;
	double t;
	
	// Loop over objects
	*time = TMAX;
	for (k = 1; k <= shapes[0].shape.len; k++) {
		switch (shapes[k].type) {
			case SPHERE: {
				if (sphereHit(&(shapes[k].shape.sp), r, &t) && t < *time) {
					hit = 1;
					*i = k;
					*time = t;
				} 
			} break;
			case TRIANGLE: {
				if (triangleHit(&(shapes[k].shape.t), r, &t) && t < *time) {
					hit = 1;
					*i = k;
					*time = t;
				} 
			} break;
			case CUBE: {
				if (cubeHit(&(shapes[k].shape.cu), r, &t) && t < *time) {
					hit = 1;
					*i = k;
					*time = t;
				} 
			} break;
			default: {
			} break;
		}
	}
	
	return hit;
}

int getRefractionRay(const vec3 normal, const vec3 direction, const float refractIndex, ray* r) {
	float NdotD = -1.0f * vec3Dot(normal, direction);
	float cos = 1.0f - ( (refractIndex*refractIndex) * (1 - (NdotD*NdotD)));
	
	if (cos < 0) {	// No refraction
		return 0;
	}
	
	r->direction = vec3UnitVector(vec3Add(vec3Mul(normal, (refractIndex*NdotD) - sqrt(cos)), 
										  vec3Mul(direction, refractIndex)));
	
	return 1;	// We have refraction
}